package com.yazi.mxz.common.service.impl;

import java.util.Iterator;
import java.util.Set;

import javax.annotation.Resource;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yazi.mxz.common.db.dao.AddressDao;
import com.yazi.mxz.common.db.dao.MemberDao;
import com.yazi.mxz.common.db.dao.RegionDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.Address;
import com.yazi.mxz.common.entity.beans.Member;
import com.yazi.mxz.common.entity.beans.Region;
import com.yazi.mxz.common.service.AddressService;

@Service("addressService")
public class AddressServiceImpl extends BasicService<Address> implements AddressService {
	private static Logger log = LoggerFactory.getLogger(AddressServiceImpl.class);
	
	@Resource
	AddressDao addressDao;
	@Resource
	RegionDao regionDao;
	@Resource
	MemberDao memberDao;

	@Override
	protected Dao<Address> getDao() {
		return addressDao;
	}
	
	@Override
	public Address add(Address address, Boolean isDefault) {
		Long memberId = address.getMember().getMemberId();
		log.debug("add：memberId={},street={}", memberId, address.getStreet());
		
		ValueFactory.validate(address);
		
		Region region = null;
		
		// 地址别名默认为最后一级地区名
		if (null == address.getAlias()) {
			region = regionDao.get(address.getRegion().getRegionId());
			address.setAlias(region.getName());
		}
		
		// 完整地区名也默认为最后一级地区名
		if (null == address.getRegionName()) {
			if (null == region) {
				region = regionDao.get(address.getRegion().getRegionId());
			}
			address.setRegionName(region.getName());
		}
		
		address.setAddressId(null);
		address = addressDao.persist(address);
		
		// 设为默认地址
		if (null != isDefault && isDefault) {
			Member member = address.getMember();
			member.setAddress(address);
			memberDao.merge(member);
		}
		
		return address;
	}

	@Override
	public Address removeByMember(Member member, long addressId) {
		log.debug("removeByMember：memberId={},addressId={}", member.getMemberId(), addressId);
		
		Address address = addressDao.get(addressId);
		if (null == address) {
			return null;
		}
		if (!address.getMember().equals(member)) {
			return null;
		}
		
		Address defAddress = null;
		// 如果要删除的地址为默认地址,则重新找一个设为默认地址
		if (address.equals(member.getAddress())) {
			Set<Address> addresses = member.getAddresses();
			addresses.remove(address);
			Iterator<Address> it = addresses.iterator();
			if (it.hasNext()) {
				defAddress = it.next();
				member.setAddress(defAddress);
			} else {
				member.setAddress(null);
			}
			memberDao.merge(member);
		}
		
		addressDao.delete(address);
		
		return defAddress;
	}

	@Override
	public void editDefaultByMember(Member member, long addressId) throws MyException {
		log.debug("modifyDefaultByMember：addressId={}", addressId);
		
		Address address = addressDao.get(addressId);
		if (null == address) {
			throw new MyEntityNotExistsException();			
		} 
		
		if (!address.equals(member.getAddress())) {
			if (!member.equals(address.getMember())) {
				throw new MyNoPermissionException();
			}
			member.setAddress(address);
			memberDao.merge(member);
		}
		
	}

	@Override
	public Address editByMember(Member member, Address address, Boolean isDefault) throws MyException {
		log.debug("modifyByMember：memberId={},addressId={}",member.getMemberId(), address.getAddressId());
		
		Address oldAddress = addressDao.get(address.getAddressId());
		if (null == oldAddress) {
			throw new MyEntityNotExistsException();
		}
		if (!oldAddress.getMember().equals(member)) {
			throw new MyNoPermissionException();
		}
		
		if (null != isDefault && isDefault) {
			member.setAddress(oldAddress);
			memberDao.merge(member);
		}
		
		// 防止篡改
		address.setMember(null);
				
		ValueFactory.combine(address, oldAddress);
		return addressDao.merge(oldAddress);
	}

}
